import 'dart:io';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:extended_image/extended_image.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:x3_component_core/utils/base_image_utils.dart';

import '../../x3_component_core.dart';
import 'base_image_hero_component.dart';
import 'base_image_hero_x2_component.dart';

class BaseImageComponent extends StatelessWidget {
  /// 图片url
  final String imageUrl;

  /// 是否开启 hero 动画 默认不开启 为 null 时 不开启
  final String hero;

  /// hero页面的背景颜色
  final Color heroBackGroundColor;

  /// 宽度
  final double width;

  /// 高度
  final double height;

  /// 自适应
  final BoxFit fit;

  /// 定位
  final Alignment alignment;

  /// 圆角
  final double circular;

  ///是否裁剪为椭圆形
  ///当宽高不一致，裁剪后为椭圆形
  ///当宽高一致，裁剪后为圆形
  final bool isClipOval;

  /// 是否是文件中加载图片
  final bool fromFile;

  /// 图片类型 用户图片 款式图片 店铺图片 默认为款式图片
  final BaseImageTypeEnum type;

  /// 如果是用户图片 当服务返回的数据为空或者是张错误的图片 则显示此Name属性的第一个字符
  final String placeholderName;

  /// 图片大小枚举 用来显示不同尺寸的图片
  final BaseImageSizeEnum size;

  /// 点击放大之后 图片可以左右滑动 因此这里要传入一个图片数组 其中要包含当前图片
  final List<dynamic> imageList;

  /// 禁用错误图片的点击事件适用于点击头像穿透到个人中心
  final bool disableErrorImagePress;

  /// 用户类型的占位符文本的大小
  final double placeholderNameFontSize;

  /// 返回加载状态
  final Function(LoadState state) stateCallBack;

  BaseImageComponent({
    Key key,
    @required this.imageUrl,
    this.hero,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.alignment = Alignment.center,
    this.circular = 0,
    this.fromFile = false,
    this.type = BaseImageTypeEnum.X3Style,
    this.size = BaseImageSizeEnum.middle,
    this.isClipOval = false,
    this.disableErrorImagePress = true,
    this.placeholderName,
    this.imageList,
    this.heroBackGroundColor,
    this.placeholderNameFontSize,
    this.stateCallBack,
  });

  @override
  Widget build(BuildContext context) {
    if (BaseUtils.isVideoFile(this.imageUrl)) return buildThumbnail(context);
    if (this.isClipOval == true) return ClipOval(child: _buildImageWidget(context));
    return ClipRRect(borderRadius: BorderRadius.circular(this.circular), child: _buildImageWidget(context));
  }

  /// 缩略图
  Widget buildThumbnail(BuildContext context) {
    return Container(
      width: this.width,
      height: this.height,
      alignment: this.alignment,
      child: VideoPlayerFirstPhoto(
        onPlayer: () => _heroImageScreen(context),
        videoUrl: this.imageUrl,
        centerWidget: Container(
          width: double.infinity,
          height: double.infinity,
          alignment: Alignment.center,
          child: Icon(Icons.play_circle_outline_outlined, color: Colors.white, size: 40.0),
        ),
      ),
    );
  }

  Widget _buildImageWidget(BuildContext context) {
    String imageUrl = BaseImageUtils.getImageUrlBySize(this.imageUrl, this.size, this.type);
    if (this.fromFile == true) {
      if (BaseUtils.isTheSVGPicture(imageUrl)) return SvgPicture.file(File(imageUrl), width: this.width, height: this.height, alignment: this.alignment, fit: this.fit);
      return ExtendedImage.file(new File(imageUrl), width: this.width, height: this.height, alignment: this.alignment, fit: this.fit);
    }
    if (BaseUtils.isTheSVGPicture(imageUrl)) return SvgPicture.network(imageUrl, width: this.width, height: this.height, alignment: this.alignment, fit: this.fit, placeholderBuilder: (context) => _buildPlaceholderImageWidget());
    return ExtendedImage.network(imageUrl, width: this.width, height: this.height, alignment: this.alignment, fit: this.fit, loadStateChanged: (ExtendedImageState state) => _loadStateChanged(context, state));
  }

  Widget _loadStateChanged(BuildContext context, ExtendedImageState state) {
    if (this.stateCallBack != null) this.stateCallBack(state.extendedImageLoadState);
    switch (state.extendedImageLoadState) {
      case LoadState.loading:
        return _buildLoadingImageWidget(context);
        break;
      case LoadState.completed:
        return _buildGestureDetectorWidget(context, state);
        break;
      case LoadState.failed:
        return _buildImageLoadingErrorWidget(state);
        break;
    }
    return SizedBox();
  }

  Widget _buildLoadingImageWidget(BuildContext context) {
    return Center(
      child: SpinKitCircle(color: Theme.of(context).primaryColor, size: 26.0),
    );
  }

  Widget _buildGestureDetectorWidget(BuildContext context, ExtendedImageState state) {
    return GestureDetector(
      onTap: this.hero != null ? () => this._heroImageScreen(context) : null,
      child: this.hero != null ? Hero(tag: this.hero, child: _buildLoadingCompletedWidget(state)) : _buildLoadingCompletedWidget(state),
    );
  }

  Widget _buildLoadingCompletedWidget(ExtendedImageState state) {
    return ExtendedRawImage(
      image: state.extendedImageInfo?.image,
      width: this.width,
      height: this.height,
      fit: this.fit,
      alignment: this.alignment,
    );
  }

  Widget _buildImageLoadingErrorWidget(ExtendedImageState state) {
    return GestureDetector(
      child: _buildPlaceholderImageWidget(),
      onTap: this.disableErrorImagePress == true ? null : () => state.reLoadImage(),
    );
  }

  /// 构建占位图
  Widget _buildPlaceholderImageWidget() {
    String placeholderImage = BaseImageUtils.getPlaceholderImage(this.type);
    if ((this.type == BaseImageTypeEnum.X2User || this.type == BaseImageTypeEnum.X2VIP || this.type == BaseImageTypeEnum.X3User) && this.placeholderName != null && this.placeholderName.length > 0) {
      Color bgColor = Color(0xFFC0CADE);
      BoxDecoration _decoration = this.isClipOval == true ? BoxDecoration(color: bgColor, shape: BoxShape.circle) : BoxDecoration(color: bgColor, borderRadius: BorderRadius.circular(this.circular));
      double fontSize = 20;
      double minSize = min(this.width, this.height);
      if (minSize >= 56.0) fontSize = 20; // 56
      if (minSize >= 44.0 && minSize < 56) fontSize = 18; // 44
      if (minSize >= 40.0 && minSize < 44) fontSize = 16; // 40
      if (minSize >= 32.0 && minSize < 40) fontSize = 15; // 32
      if (minSize <= 32) fontSize = 15; // 更小
      if (this.placeholderNameFontSize != null) fontSize = this.placeholderNameFontSize;
      return Container(width: this.width, height: this.height, alignment: Alignment.center, decoration: _decoration, child: Text(this.placeholderName[0], style: TextStyle(fontSize: fontSize, color: Colors.white)));
    }

    if (BaseUtils.isTheSVGPicture(placeholderImage)) return SvgPicture.asset(placeholderImage, width: this.width, height: this.height, alignment: this.alignment, fit: this.fit);
    return Image.asset(placeholderImage, width: this.width, height: this.height, alignment: this.alignment, fit: this.fit);
  }

  void _heroImageScreen(BuildContext context) {
    if (this.type == BaseImageTypeEnum.X3Style || this.type == BaseImageTypeEnum.X3Depot || this.type == BaseImageTypeEnum.X3User) {
      this._heroX3ImageScreen(context);
    } else {
      this._heroX2ImageScreen(context);
    }
  }

  void _heroX2ImageScreen(BuildContext context) {
    if (imageUrl == null || imageUrl.length == 0) return;
    String placeholderImage = BaseImageUtils.getPlaceholderImage(this.type);
    String currentShowImageUrl = BaseImageUtils.getImageUrlBySize(this.imageUrl, this.size, this.type);
    Navigator.push(context, PageRouteBuilder(pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) => BaseImageHeroX2Component(animation: animation, imageUrl: this.imageUrl, currentShowImageUrl: currentShowImageUrl, imageList: this.imageList, hero: this.hero, backgroundColor: this.heroBackGroundColor, placeholderImage: placeholderImage, type: this.type), fullscreenDialog: true));
  }

  void _heroX3ImageScreen(BuildContext context) {
    String imageUrl = BaseUtils.initImageUrl(this.imageUrl);
    if (imageUrl == null || imageUrl.length == 0) return;
    String placeholderImage = BaseImageUtils.getPlaceholderImage(this.type);
    String currentShowImageUrl = BaseImageUtils.getImageUrlBySize(this.imageUrl, this.size, this.type);
    Navigator.push(context, PageRouteBuilder(pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) => BaseImageHeroComponent(animation: animation, imageUrl: this.imageUrl, currentShowImageUrl: currentShowImageUrl, imageList: this.imageList, hero: this.hero, backgroundColor: this.heroBackGroundColor, placeholderImage: placeholderImage), fullscreenDialog: true));
  }
}
